package com.ipan.jfinal.tdo;

import java.io.File;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.excel.read.listener.ReadListener;
import com.ipan.jfinal.tdo.config.Mp;
import com.ipan.jfinal.tdo.config.Tpl;
import com.ipan.jfinal.tdo.out.CsvOutput;
import com.ipan.jfinal.tdo.out.DbOutput;
import com.ipan.jfinal.tdo.transform.Transducer;
import com.ipan.kits.base.ExceptionUtil;
import com.ipan.kits.reflect.ReflectionUtil;
import com.ipan.kits.xconverter.XTypeConverter;
import com.ipan.poi.easyexcel.EasyExcelUtil;
import com.ipan.poi.easyexcel.EasyExcelUtil2;
import com.ipan.poi.easyexcel.ehcache2.SimpleReadCacheSelector2;
import com.ipan.poi.easyexcel.patch305.EasyExcel2;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;

/**
 * 输出工具类
 * 
 * @author iPan
 * @date 2023-05-02
 */
public class OutputKits {
	
	// -- 小文件同步输出（支持xls、xlsx、csv；自定义类型，重写一下rowToJavaBean方法；） -- //
	public static void outToDb(Tpl tpl, List data, Class beanClass) {
		new DbOutput(tpl, data, beanClass).execute();
	}
	
	public static void outToCsv(Tpl tpl, List data, File fout) {
		new CsvOutput(tpl, data, fout).execute();
	}
	
	public static void outToDb(Tpl tpl, File srcFile, Class beanClass) {
		List data = EasyExcelUtil.syncRead(srcFile);
		new DbOutput(tpl, data, beanClass).execute();
	}
	
	public static void outToDb2(Tpl tpl, File srcFile, Class beanClass) { // 推荐（兼容ehcache2）
		List data = EasyExcelUtil2.syncRead(srcFile);
		new DbOutput(tpl, data, beanClass).execute();
	}
	
	public static void outToCsv(Tpl tpl, File srcFile, File fout) {
		List data = EasyExcelUtil.syncRead(srcFile);
		new CsvOutput(tpl, data, fout).execute();
	}
	
	public static void outToCsv2(Tpl tpl, File srcFile, File fout) { // 推荐（兼容ehcache2）
		List data = EasyExcelUtil2.syncRead(srcFile);
		new CsvOutput(tpl, data, fout).execute();
	}
	
	// -- 大文件异步输出（仅支持xls、xlsx、csv） -- //
	public static void bigFileToDb(Tpl tpl, Class beanClass, File fin, ReadListener readListener) { // 参考ReadBigFileToDbListener
		int index = tpl.getIndex();
		int headRowNumber = (index <= 0) ? 1 : index + 1; // 从1开始计数，配置是从0开始计数；
		Db.tx(new IAtom() { // 在一个事务内完成
			@Override
			public boolean run() throws SQLException {
				EasyExcel2.read(fin, readListener)
					.readCacheSelector(new SimpleReadCacheSelector2())
					.sheet()
					.headRowNumber(headRowNumber)
					.doRead();
				return true;
			}
		});
	}
	
	public static void bigFileToCsv(Tpl tpl, Class beanClass, File fin, ReadListener readListener) { // 参考ReadBigFileToCsvListener
		int index = tpl.getIndex();
		int headRowNumber = (index <= 0) ? 1 : index + 1; // 从1开始计数，配置是从0开始计数；
		EasyExcel2.read(fin, readListener)
			.readCacheSelector(new SimpleReadCacheSelector2())
			.sheet()
			.headRowNumber(headRowNumber)
			.doRead();
	}
	
	// -- 辅助工具 -- //
	/**
	 * 是否为空行
	 * 
	 * @param values 一行数据
	 * @return true 空行 false 不是空行
	 */
	public static boolean isBlankLine(Collection<String> values) {
		if (values == null || values.size() < 1) return true;
		for (String item : values) {
			if (StringUtils.isNotBlank(item)) return false;
		}
		return true;
	}
	
	/**
	 * 获取列值
	 * 
	 * @param rowMap 一行数据
	 * @param mp 列配置
	 * @param keyType 源数据格式（1 数字key 2 字符串key）
	 * @return 列值
	 */
	public static String getCellValue(Map rowMap, Mp mp, int keyType) {
		if (rowMap == null || mp == null) return null;
		return getCellValue(rowMap, mp.getSrcVal(), keyType);
	}
	
	public static String getCellValue(Map rowMap, String srcVal, int keyType) {
		if (rowMap == null || StringUtils.isBlank(srcVal)) return null;
		Object result = null;
		if (keyType == Tpl.KEY_TYPE_1) {
			Integer key = Integer.valueOf(srcVal);
			result = rowMap.get(key);
		} else {
			result = rowMap.get(srcVal);
		}
		return (result == null) ? null : (result instanceof String) ? (String)result : result.toString().trim();
	}
	
	public static <E> E rowToJavaBean(Tpl tpl, Map row, int rowIndex, Class<E> beanClass) {
		E bean = null;
		try {
			// 创建JavaBean
			bean = ReflectionUtil.createInstance(beanClass);
			// 格式转换
			Map retData = Transducer.me().transform(row, rowIndex, tpl); // 同步方式、异步方式的转换器是一致的
			// 给JavaBean赋值
			List<Mp> listMp = tpl.getMappings();
			for (Mp mp : listMp) {
				String targetVal = OutputKits.getCellValue(retData, mp, tpl.getKeyType()); // 同步方式、异步方式的转换器是一致的
				String toKey = mp.getToVal();
				Field toField = ReflectionUtil.getField(beanClass, toKey);
				Class<?> toType = toField.getType();
				Object toVal = XTypeConverter.me().convert(toType, targetVal);
				toField.set(bean, toVal);
			}
		} catch (Exception e) {
			throw ExceptionUtil.wrapRuntime(e);
		}
		return bean;
	}
	
}
